<template>
    <!-- 按钮选项组 -->
    <div class="flex flex-wrap gap-2 ml-2 mb-2">
        <!-- 调整行高 -->
        <el-tooltip effect="dark" content="调整行高" placement="bottom">
            <el-input-number style="width: 120px" v-model="rowHeight" :min="80" :max="120" :step="5" step-strictly />
        </el-tooltip>
        <!-- 搜索框+按钮 -->
        <el-input
            style="width: 180px"
            v-model="searchUserValue"
            placeholder="请输入权限关键字查询"
            clearable
            @keydown.enter="searchUserEvent"
            @clear="inputClearEvent"
        />
        <el-button @click="searchUserEvent" :icon="Search">搜索</el-button>
        <!-- 选项组 -->
        <el-button-group>
            <el-button type="primary" @click="getAllUserEvent" :icon="Refresh">刷新</el-button>
        </el-button-group>
    </div>
    <div style="height: calc(100vh - 120px)">
        <el-auto-resizer>
            <template #default="{ height, width }">
                <FTableV2
                    v-model="selected"
                    :data="data"
                    :width="width"
                    :height="height"
                    :row-height="rowHeight"
                    :other-column="otherColumn"
                    :disable="disable"
                    @update-data="updateData"
                ></FTableV2>
            </template>
        </el-auto-resizer>
    </div>

    <!-- 添加/编辑用户权限弹窗 -->
    <el-dialog v-model="updateUserPermissionVisible" :close-on-click-modal="false" width="80%" :show-close="false">
        <!-- 标题 -->
        <template #header="{ close, titleId, titleClass }">
            <div class="my-header">
                <h4 :id="titleId" :class="titleClass">编辑角色组</h4>
                <el-button type="danger" @click="close">
                    <el-icon class="el-icon--left"><CircleCloseFilled /></el-icon>
                    关闭
                </el-button>
            </div>
        </template>
        <div class="w-full flex flex-wrap justify-center mb-4 mt-4">
            <el-transfer
                class="w-full flex justify-center items-center"
                v-model="selectedRole"
                :data="RoleList"
                :titles="['角色列表', '已选角色']"
                filterable
                :filter-method="updateUserRoleFilterMethod"
                filter-placeholder="搜索关键字"
                @change="updateUserRoleChangeEvent"
            />
            <el-button @click="updateUserRoleSubmitEvent">提交</el-button>
        </div>
    </el-dialog>
</template>

<script setup lang="tsx">
import { getAllRole, getAllUser, updateUser, updateUserRoleApi } from '@api/system/index';
import { Column, ElButton, ElTag, TransferKey } from 'element-plus';
import { Search, Refresh, CircleCloseFilled } from '@element-plus/icons-vue';
import { useDictionaryStore } from '@/store/modules/dictionary';
import { checkPermi, checkRole } from '@/utils/permission';

onMounted(() => {
    generateDisableColumn();
    getAllUserEvent();
});

/* ******************************通用属性/方法****************************** */
// 字典数据
const useDictionary = useDictionaryStore();
// 表格选中数据
const selected = reactive<string[]>([]);
// 获取用户数据
const getAllUserEvent = () => {
    // 清空数据
    dataCache.splice(0);
    data.splice(0);
    selected.splice(0);
    // 获取所有系统用户
    getAllUser().then((res) => {
        res.data.forEach((item, index) => {
            item.checked = false;
            item.order = index + 1;
            item.editing = false;
            data.push(item);
            dataCache.push(item);
        });
    });
};
// 更新表格的方法
const updateData = (id: string, field: Column['dataKey'], value: string | boolean | number | any[]) => {
    if (checkPermi(['system:user'])) {
        updateUser({ id, field, value }).then(() => {
            ElMessage.success('更新用户信息成功');
            getAllUserEvent();
        });
    }
};

/* ******************************搜索栏属性/方法****************************** */
const searchUserValue = ref('');
// 搜索事件
const searchUserEvent = () => {
    if (searchUserValue.value == '') {
        // 原始数据
        data.length = 0;
        dataCache.forEach((item) => {
            data.push(item);
        });
    } else {
        // 筛选数据
        data.length = 0;
        dataCache.forEach((item) => {
            if (
                item.username.includes(searchUserValue.value) ||
                item.phone.includes(searchUserValue.value) ||
                item.roles.some((item) => item.description.includes(searchUserValue.value))
            ) {
                data.push(item);
            }
        });
    }
};
// 输入框清空事件
const inputClearEvent = () => {
    // 原始数据
    data.length = 0;
    dataCache.forEach((item) => {
        data.push(item);
    });
};

/* ******************************组件el-table-v2 表格属性****************************** */
// 表格数据
const data = reactive<AjaxResponse['userData']>([]);
// 缓存数据
let dataCache: AjaxResponse['userData'] = [];
// FTableV2 禁用列
const disable = reactive<string[]>([]);
// 表格独有的column
const otherColumn = reactive<{ [key: string]: Column<any> }>({
    roles: {
        key: 'roles',
        dataKey: 'roles',
        width: 300,
        align: 'center',
        title: '角色组',
        cellRenderer: ({ rowData, column }) => {
            const onClick = () => {
                // 选中用户
                selectedUser.value = rowData._id;
                // 清空已选角色
                selectedRole.value.length = 0;
                // 已选角色
                rowData[column.dataKey!].forEach((i: any) => {
                    selectedRole.value.push(i._id);
                });

                // 加载所有角色
                getAllRole().then((res) => {
                    RoleList.length = 0;
                    res.data.forEach((item) => {
                        RoleList.push({
                            key: item._id,
                            label: item.description,
                            disabled: false,
                        });
                    });
                });

                // 显示弹窗
                updateUserPermissionVisible.value = true;
            };
            // 遍历每个组，显示对应的角色名称
            return (
                <div>
                    <div class={'flex flex-wrap'}>
                        {rowData[column.dataKey!].map((i: any) => {
                            return <ElTag type={'primary'}>{i.description}</ElTag>;
                        })}
                    </div>
                    <ElButton type={'warning'} text onClick={onClick}>
                        编辑角色
                    </ElButton>
                </div>
            );
        },
    },
});
// 生成禁用列 -- 根据字典提供的权限加工otherColumn对象生成禁用列表
const generateDisableColumn = () => {
    // 遍历所有字段
    for (const key in otherColumn) {
        if (Object.prototype.hasOwnProperty.call(otherColumn, key)) {
            // 获取key在字典中的数据
            const { definition, roles } = useDictionary.getDictionaryUseField(key);
            // 判断是否为空
            if (definition == '') {
                disable.push(key);
                continue;
            }
            // 判断当前用户是否有权限查看该字段
            if (!checkRole(roles)) {
                disable.push(key);
            }
        }
    }
};
// 表格高度
const rowHeight = ref(80);

/* ******************************添加/编辑用户权限弹窗属性/方法****************************** */
// 弹窗是否显示
const updateUserPermissionVisible = ref(false);
// 所有角色列表
const RoleList = reactive<
    {
        key: string;
        label: string;
        disabled: boolean;
    }[]
>([]);
// 已选用户
const selectedUser = ref<string>('');
// 已选角色
const selectedRole = ref<string[]>([]);
// 需要被上传到的角色
const updateUserRole = ref<string[]>([]);
// 更新用户角色筛选方法
const updateUserRoleFilterMethod = (queryString: string, item: any) => {
    return item.label.includes(queryString);
};
// 更新用户角色改变事件
const updateUserRoleChangeEvent = (value: TransferKey[]) => {
    updateUserRole.value.length = 0;
    value.forEach((item) => {
        updateUserRole.value.push(item as string);
    });
};
// 更新用户角色提交事件
const updateUserRoleSubmitEvent = () => {
    // 提交更新用户角色
    updateUserRoleApi(selectedUser.value, updateUserRole.value).then((res) => {
        ElMessage.success(res.message);
        // 关闭弹窗
        updateUserPermissionVisible.value = false;
        // 刷新数据
        getAllUserEvent();
    });
};
</script>

<style scoped lang="scss">
.my-header {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    gap: 16px;
}
</style>
